﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;

namespace System.Security
{
    /// <summary>
    /// Extends SecureString to allow easier creation and access.
    /// </summary>
    public static class SecureStringExtensions
    {
        /// <summary>
        /// Appends the contents of the <see cref="string"/>.
        /// </summary>
        /// <param name="str">secure string to append to</param>
        /// <param name="stringToAppend">string which shall be appended</param>
        public static void Append(this SecureString str, string stringToAppend)
        {
            Contract.Requires<ArgumentNullException>(str != null, "str");
            Contract.Requires<ArgumentException>(!string.IsNullOrWhiteSpace(stringToAppend), "initString");

            foreach (var c in stringToAppend.ToArray())
            {
                str.AppendChar(c);
            }
        }

        /// <summary>
        /// Decodes the secure content to a plain <see cref="string"/>.
        /// </summary>
        /// <param name="str">secure string to decode</param>
        /// <returns>decoded string</returns>
        public static string Decode(this SecureString str)
        {
            IntPtr ptr = Marshal.SecureStringToBSTR(str);
            return Marshal.PtrToStringUni(ptr);
        }

    }
}